﻿using System;
using System.Text;
using System.Drawing;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;

public static partial class glDRIVE
{
    /*
    函数 gl.cplx
    复形调优法
    void (* s)(int, int, double[], double[], double[], double[]),计算函数约束条件中的上、下限以及条件值的函数名。
    double (* f)(double[], int))计算目标函数值的函数名。
    参数 n: 变量个数。
    参数 m: 函数约束条件的个数。
    参数 a: a[n]依次存放常数约束条件中的变量x的下界。
    参数 b: b[n]依次存放常数约束条件中的变量x的上界。
    参数 eps: 控制精度要求。
    参数 x: x[n+1]前n个分量存放初始复形的第1个顶点坐标值（要求满足所有约束条件），返回极小值点各坐标值；最后一个分量返回极小值。
    参数 xx: xx[n+1][2n]前n行返回最后复形的2n个顶点坐标（1列为1个顶点）；最后一行返回最后复形的2n个顶点上的目标函数值。
    参数 alpha: 存放反射系数。
    参数 inter: 最多迭代
    返回值 函数返回迭代次数。本函数最多迭代500次。
    */

    public static unsafe string drive_cplx()
    {
        int i, j;
        double eps;
        double[] a = new double[2];
        double[] b = new double[2];
        double[] x = new double[3];
        double[,] xx = new double[3, 4];

        x[0] = 0.0;
        x[1] = 0.0;
        a[0] = 0.0;
        a[1] = 0.0;
        b[0] = 1.0e+35;
        b[1] = b[0];
        eps = 1.0e-30;

        gl.s_nm_xa_ya_ua_va = cplxs;
        gl.f_xa_n = cplxf;
        i = gl.cplx(2, 2, a, b, eps, x, xx, alpha: 1.3);

        string rs = "";
        rs += gl.html_table("复形顶点坐标与目标函数值(迭代次数=" + i + ")", xx);
        rs += gl.html_table("极小值点坐标与极小值", x);
        return rs;
    }

    // 计算目标函数值
    private static unsafe double cplxf(double* x, int n)
    {
        double y;
        //n = n;
        y = -(9.0 - (x[0] - 3.0) * (x[0] - 3.0));
        y = y * x[1] * x[1] * x[1] / (27.0 * Math.Sqrt(3.0));
        return (y);
    }

    // 计算函数约束条件中的上、下限以及条件值
    private static unsafe double cplxs(int n, int m, double* x, double* c, double* d, double* w)
    {
        //n = n; m = m;
        c[0] = 0.0;
        c[1] = 0.0;
        d[0] = x[0] / Math.Sqrt(3.0);
        d[1] = 6.0;
        w[0] = x[1];
        w[1] = x[0] + x[1] * Math.Sqrt(3.0);
        return 0;
    }
}